#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
import re

reload(sys)
sys.setdefaultencoding("utf-8")
# 需要合并数据的字段，防止其他不需要合并的数字字段被合并
mergeKeys = {"ynse", "asysljsxse", "ajybfjsxse", "mdtbfckxse", "msxse", "jxse", "xxse"}


def json_convert():
    # data = abc.get("data")
    # if data is not None:
    #     del abc["data"]

    res = {}
    # 取出原json其他数据并放到返回结果中
    # for k in abc:
    #     res[k] = abc[k]
    #
    # # 如果data为空返回空json
    # if data is None:
    #     res["data"] = {}
    #     return json.dumps(res, False)

    newData = data.copy()

    # 纳税人登记信息
    syptSwdjxx = getJsonObject(data.get("jbxx"))

    if syptSwdjxx != {}:
        del newData["jbxx"]

    syptSwdjxxMap = {"frxm": "FDDBRHFZRHYZXM", "frsfzjlx": "FDDBRHFZRHYZSFZJZL_DM", "frsfzjhm": "FDDBRHFZRHYZSFZJHM",
                     "frlxdh": "FDDBRHFZRHYZYDDH"}
    syptSwdjxx = changeJsonKey([syptSwdjxx], syptSwdjxxMap)[0]

    # 纳税人资格类型
    zzsnsrzg = syptSwdjxx.get("zzsnsrzg")
    if zzsnsrzg is not None:
        del syptSwdjxx["zzsnsrzg"]
    if zzsnsrzg == "一般纳税人":
        syptSwdjxx["NSRZG_DM"] = "201"
    elif zzsnsrzg == "小规模纳税人" or zzsnsrzg is None:
        syptSwdjxx["NSRZG_DM"] = "204"
    else:
        syptSwdjxx["NSRZG_DM"] = zzsnsrzg

    newData["syptSwdjxx"] = [syptSwdjxx]

    # 纳税信用等级
    jbxx = getJsonObject(data.get("jbxx"))
    syptSwpjxx = {}
    syptSwpjxx["SWXYPJSJ"] = jbxx.get("xydjnd")
    syptSwpjxx["SWXYPJ"] = jbxx.get("xydj")
    newData["syptSwpjxx"] = [syptSwpjxx]

    # 增值税小规模申报信息
    newData["syptZzsXgm"] = []

    # 申报信息去重
    sbxx = getJsonArray(data.get("sbxx"))
    sbxxList = []
    sbxx_set = {}
    deduplicationSet = set()
    for i in sbxx:
        zsxmdm = i.get("zsxmdm")
        zspmdm = i.get("zspmdm")
        pzxh = i.get("pzxh")
        skssqq = i.get("skssqq")
        skssqz = i.get("skssqz")
        ynse = i.get("ynse")
        if zsxmdm is not None or zspmdm is not None and pzxh is not None and skssqq is not None and skssqz is not None and ynse is not None:
            keyStr = str(zsxmdm) + str(zspmdm) + str(pzxh) + str(skssqq) + str(skssqz) + str(ynse)
            if keyStr not in deduplicationSet:
                deduplicationSet.add(keyStr)
                sbxx_set[str(skssqq) + str(skssqz) + str(zsxmdm)] = mergeJson(sbxx_set.get(str(skssqq) + str(skssqz) + str(zsxmdm)), i)

    for i in sbxx_set:
        sbxxList.append(sbxx_set[i])

    # 增值税一般纳税人申报
    zsxx = sbxxList
    syptZzsybnsr = []
    # 一般纳税人临时json，key为年月，value为当月数据
    for item in zsxx:
        try:
            zsxmdm = item.get("zsxmdm")
            if zsxmdm == "10101":
                ybnsrItem = {}
                skssqq = item.get("skssqq")
                ybnsrItem["skssqq"] = skssqq

                skssqz = item.get("skssqz")
                ybnsrItem["skssqz"] = skssqz
                ybr_skssqz = date_format(skssqz)
                if ybr_skssqz is not None:
                    ybnsrItem["ND"] = str(ybr_skssqz.year)
                    if ybr_skssqz.month < 10:
                        ybnsrItem["YF"] = "0" + str(ybr_skssqz.month)
                    else:
                        ybnsrItem["YF"] = str(ybr_skssqz.month)
                else:
                    continue

                # 按适用税率计税销售额
                value = item.get("asysljsxse")
                ybnsrItem["ASYSLJSDNSJCYBJSE"] = value

                # 按简易办法计税销售额
                value = item.get("ajybfjsxse")
                ybnsrItem["AJYZSBFZSHWXSE"] = value

                # 免、抵、退办法出口销售额
                value = item.get("mdtbfckxse")
                ybnsrItem["MDTBFCKHWXSE"] = value

                # 免税销售额
                value = item.get("msxse")
                ybnsrItem["MSHWJLWXSE"] = value

                # 应纳税额合计
                value = item.get("ynse")
                ybnsrItem["YNSEHJ"] = value

                # 进项税额
                value = item.get("jxse")
                ybnsrItem["JXSE"] = value

                # 应纳税额合计
                value = item.get("xxse")
                ybnsrItem["XXSE"] = value

                syptZzsybnsr.append(ybnsrItem)
        except:
            continue
    newData["syptZzsybnsr"] = syptZzsybnsr

    # 所得税A类月、季申报
    zsxx = sbxxList


    syptQysdsA1 = []
    for item in zsxx:
        try:
            zsxmdm = item.get("zsxmdm")
            if zsxmdm == "10104":
                sdsA1Item = {}
                skssqq = item.get("skssqq")
                sdsA1Item["skssqq"] = skssqq
                a1_skssqq = date_format(skssqq)

                skssqz = item.get("skssqz")
                sdsA1Item["skssqz"] = skssqz
                a1_skssqz = date_format(skssqz)
                if a1_skssqz is not None and (a1_skssqz.month - a1_skssqq.month != 11):
                    sdsA1Item["ND"] = str(a1_skssqz.year)
                    if a1_skssqz.month < 10:
                        sdsA1Item["YF"] = "0" + str(a1_skssqz.month)
                    else:
                        sdsA1Item["YF"] = str(a1_skssqz.month)
                else:
                    continue

                # 应纳所得税额
                value = item.get("ynse")
                sdsA1Item["YNSSDE"] = value

                # 本期应补（退）所得税额/税务机关确定的本期应纳所得税额
                value = item.get("ybtse")
                sdsA1Item["BQSJYBTSDSE"] = value

                syptQysdsA1.append(sdsA1Item)
        except:
            continue
    # 四川a1表需要替换的字段，原由：a1表数据为累加数据，需做拆分处理
    syptQysdsA1 = sorted(syptQysdsA1, key=lambda a: a.get("skssqz")[:7], reverse=True)
    a1_items = []
    prev = None
    for i, item in enumerate(syptQysdsA1):
        item["YNSSDE_LJ"] = item.get("YNSSDE")
        item["BQSJYBTSDSE_LJ"] = item.get("BQSJYBTSDSE")
        if check_item(item):
            if prev is not None:
                a1_items.append(minus_item(prev, item, 1))
            if i == len(syptQysdsA1) - 1:
                end_date = date_format(item.get("skssqz"))
                if end_date is not None:
                    a1_items.append(minus_item(item, dict(), end_date.month / 3))
                else:
                    a1_items.append(minus_item(item, dict(), 1))
            prev = item
        else:
            a1_items.append(item)
    newData["syptQysdsA1"] = a1_items

    # 所得税A类年报
    zsxx = sbxxList
    syptQysdsNd = []
    for item in zsxx:
        try:
            zsxmdm = item.get("zsxmdm")
            if zsxmdm == "10104":
                sdsNdItem = {}
                skssqq = item.get("skssqq")
                sdsNdItem["skssqq"] = skssqq
                skssqq = date_format(skssqq)
                skssqz = item.get("skssqz")
                sdsNdItem["skssqz"] = skssqz
                skssqz = date_format(skssqz)
                if skssqz is not None and (skssqz.month - skssqq.month == 11):
                    sdsNdItem["ND"] = str(skssqz.year)
                else:
                    continue

                # 应纳税所得额
                value = item.get("ynse")
                sdsNdItem["YNSDSE"] = value

                syptQysdsNd.append(sdsNdItem)
        except:
            continue
    newData["syptQysdsNd"] = syptQysdsNd

    # 欠税信息
    syptQsye = getJsonArray(data.get("qsxx"))
    syptQsyeMap = {"qsye": "SE"}
    if syptQsye != []:
        del newData["qsxx"]
    newData["syptQsye"] = changeJsonKey(syptQsye, syptQsyeMap)

    # 违法信息
    syptWfwzxx = getJsonArray(data.get("wfxx"))
    syptWfwzxxMap = {"sswflxdm": "WFWZLX_DM", "sswfxwclztdm": "WFXWCLZT_DM"}
    if syptWfwzxx != []:
        del newData["wfxx"]
    for wfwzItem in syptWfwzxx:
        ssqj = wfwzItem.get("ssqjq")
        wfwzItem["DJRQ"] = None
        wfwzItem["LARQ"] = None
        try:
            ssqj = ssqj.split(u'至', 1)[0]
        except:
            continue
        if ssqj is not None:
            wfwzItem["DJRQ"] = ssqj
            wfwzItem["LARQ"] = ssqj

    newData["syptWfwzxx"] = changeJsonKey(syptWfwzxx, syptWfwzxxMap)

    res["data"] = newData
    return json.dumps(res, False)


def isfloat(x):
    try:
        if isinstance(float(x), float):
            if str(x) in ["inf", "infinity", "INF", "INFINITY", "True"]:
                return False
            else:
                return True
        else:
            return False
    except:
        return False


def changeJsonKey(jsonArr, jsonMap):
    """
    替换掉json数组中的所有需要替换的字段
    :param jsonArr: 需要替换的json
    :param jsonMap: 替换的映射json，key为原字段，value为替换后的字段
    :return:
    """
    for obj in jsonArr:
        items = jsonMap.items()
        for k, v in items:
            try:
                value = obj.get(k)
                if value is not None:
                    obj[v] = value
                    del obj[k]
                else:
                    obj[v] = obj.get(v)
            except:
                continue

    return jsonArr


def mergeJson(oldJson, newJson):
    """
    合并两个json，除年度和月份外其他字段合并，如果是数字，合并结果是加和，字符串则取后者
    :param oldJson:
    :param newJson:
    :return:
    """
    if oldJson is None:
        return newJson
    if newJson is None:
        return oldJson
    result = {}

    for (k, v) in newJson.items():
        value = oldJson.get(k)
        if k == "skssqq" or k == "skssqz":
            result[k] = v
        else:
            if (isfloat(v) or isfloat(value)) and k in mergeKeys:
                v = float(v) if isfloat(v) else 0
                value = float(value) if isfloat(value) else 0
                result[k] = v + value
            else:
                result[k] = value
    return result


def date_format(time):
    try:
        import re
        import datetime
        r1 = re.compile(u'年|月|日')
        time = r1.sub('.', time)
        try:
            date = datetime.datetime.strptime(time, '%Y.%m.%d')
        except:
            try:
                date = datetime.datetime.strptime(time, '%Y-%m-%d')
            except:
                try:
                    date = datetime.datetime.strptime(time, '%Y/%m/%d')
                except:
                    try:
                        r = re.compile(r'\D+')
                        tmp = r.sub('', time)
                        if len(tmp) > 8:
                            tmp = tmp[:8]
                        date = datetime.datetime.strptime(tmp, '%Y%m%d')
                    except:
                        date = None
        return date
    except:
        return None


def check_item(item):
    start_date = date_format(item.get("skssqq"))
    end_date = date_format(item.get("skssqz"))
    if start_date is not None and end_date is not None and end_date.month in [3, 6, 9, 12] \
            and end_date.month - start_date.month == 2:
        return True
    else:
        return False


def minus(val1, val2, season):
    if isfloat(val1) and isfloat(val2):
        return round((float(val1) - float(val2)) / season, 4)
    elif isfloat(val1):
        return round(float(val1) / season, 4)
    else:
        return val1


def minus_item(curr_item, next_item, season):
    curr_date = date_format(curr_item.get("skssqz"))
    next_date = date_format(next_item.get("skssqz"))
    if next_date is not None and curr_date.year != next_date.year:
        return curr_item
    curr_item["YNSSDE"] = minus(curr_item.get("YNSSDE"), next_item.get("YNSSDE"), season)
    curr_item["BQSJYBTSDSE"] = minus(curr_item.get("BQSJYBTSDSE"), next_item.get("BQSJYBTSDSE"), season)
    return curr_item


def getJsonObject(jsonObj):
    try:
        return jsonObj if isinstance(jsonObj, dict) else {}
    except:
        return {}


def getJsonArray(jsonArr):
    try:
        return jsonArr if isinstance(jsonArr, list) else []
    except:
        return []


def getStr(str):
    if str is None:
        return ""
    else:
        return str


if __name__ == "__main__":
    file_obj = open(r"../data/aaa_sc.json", "r")
    content = file_obj.read()
    abc = json.loads(content, strict=False)
    aa = json_convert()
    print aa

result = json_convert()
